<template>
	<div :id="elementId" class="scratchCard">
		<div class="result" v-show="showLucky">
			<slot name="result"></slot>
			<img :src="myresultImg" alt="" class="pic" />
		</div>
		<canvas id="scratchCanvas"></canvas>
		<!-- <div class="cavastext" v-if="start" @touchstart="StartTouch()">点我刮大奖！</div> -->
	</div>
</template>
<script>
	export default {
		name: 'vueScratchCard',
		data() {
			return {
				supportTouch: false, //是否支持touch事件
				events: [], //touch事件 or mouse事件合集
				startMoveHandler: null, //touchstart or mousedown 事件
				moveHandler: null, //touchmove or mousemove 事件
				endMoveHandler: null, //touchend or mouseend 事件
				showLucky: false, //显示隐藏抽奖结果
				firstTouch: true, //是否第一次touchstart or mousedown
				canMove: false,
				start: true,
				myresultImg: '',
			}
		},
		props: {
			elementId: {
				//组件最外层DOM的id属性
				type: String,
				default: 'scratch'
			},
			moveRadius: {
				//刮刮范围
				type: Number,
				default: 15
			},
			ratio: {
				//要求刮掉的面积占比，达到这个占比后，将会自动把其余区域清除
				type: Number,
				default: 0.3
			},
			startCallback: {
				//第一次刮回调函数
				type: Function,
				default: function() {}
			},
			clearCallback: {
				//达到ratio占比后的回调函数
				type: Function,
				default: function() {}
			},
			coverColor: {
				//刮刮卡遮罩颜色
				type: String,
				default: '#C5C5C5'
			},
			coverImg: {
				//刮刮卡遮罩图片
				type: String
			},
			resultImg: {
				//中奖的图
				type: String,
				default: 'https://raw.githubusercontent.com/ZENGzoe/imagesCollection/master/2018/default.jpg'
			},
			ismove: {
				type: Boolean,
				default: false
			}
		},
		mounted: function() {
			this.$nextTick(() => {
				this.init()
			})
			this.myresultImg = this.resultImg
			// console.log('resultImg:', this.resultImg)
			this.canMove = this.ismove
		},
		watch: {
			ismove(val) {
				this.canMove = val
			},
			resultImg(val) {
				// console.log('------------:,', val)
				this.myresultImg = val
			}
		},
		methods: {
			init: function() {
				if (!this.isSupportCanvas()) {
					alert('当前浏览器不支持canvas')
					return
				}

				const canvasWrap = document.getElementById(this.elementId)
				this.canvas = canvasWrap.querySelector('#scratchCanvas')
				this.ctx = this.canvas.getContext('2d')
				// this.ctx.fillText('刮我赢大奖',0,0,50)
				// this.ctx.fillStyle = '#FEEEC2';
				// this.ctx.font = 'italic 30px 黑体'
				// this.ctx.textAlign = 'center'

				this.canvas.width = canvasWrap.clientWidth
				this.canvas.height = canvasWrap.clientHeight


				this.createCanvasStyle()
				this.bindEvent()
			},
			isSupportCanvas: function() {
				var elem = document.createElement('canvas')
				return !!(elem.getContext && elem.getContext('2d'))
			},
			createCanvasStyle: function() {
				var _this = this
				//当传入coverImg时，优先使用图片，否则使用颜色作为刮刮卡遮罩
				if (this.coverImg) {
					var coverImg = new Image()
					coverImg.src = this.coverImg
					coverImg.onload = function() {
						_this.ctx.drawImage(coverImg, 0, 0, _this.canvas.width, _this.canvas.height)
					}
				} else {
					_this.ctx.fillStyle = _this.coverColor
					_this.ctx.fillRect(0, 0, _this.canvas.width, _this.canvas.height)
				}
			},
			bindEvent: function() {
				if ('ontouchstart' in window) this.supportTouch = true
				this.events = this.supportTouch ? ['touchstart', 'touchmove', 'touchend'] : ['mousedown', 'mousemove',
					'mouseup'
				]
				this.addEvent()
			},
			addEvent: function() {
				this.startMoveHandler = this.startEventHandler.bind(this)
				this.canvas.addEventListener(this.events[0], this.startMoveHandler, false)
			},
			startEventHandler: function(e) {
				console.log('startEventHandler')
				e.preventDefault()

				if (this.firstTouch) {
					this.startCallback()
					this.firstTouch = false
				}
				this.showLucky = true
				this.moveHandler = this.moveEventHandler.bind(this)
				this.endMoveHandler = this.endEventHandler.bind(this)
				this.canvas.addEventListener(this.events[1], this.moveHandler, false)
				document.addEventListener(this.events[2], this.endMoveHandler, false)
			},
			moveEventHandler: function(e) {
				console.log('moveEventHandler')
				if (this.ismove) {
					e.preventDefault()

					e = this.supportTouch ? e.touches[0] : e

					const canvasPos = this.canvas.getBoundingClientRect(),

						mouseX = e.pageX - canvasPos.left,
						mouseY = e.pageY - canvasPos.top

					this.ctx.beginPath()
					this.ctx.fillStyle = '#FFFFFF'
					this.ctx.globalCompositeOperation = 'destination-out'
					this.ctx.arc(mouseX, mouseY, this.moveRadius, 0, 2 * Math.PI)
					this.ctx.fill()
				}
			},
			endEventHandler: function(e) {
				console.log('endEventHandler')
				e.preventDefault()

				this.canvas.removeEventListener(this.events[1], this.moveHandler, false)
				document.removeEventListener(this.events[2], this.endMoveHandler, false)
				this.endMoveHandler = null
				this.caleArea()
			},
			caleArea: function() {
				let pixels = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height),
					transPixels = []

				pixels.data.map((item, i) => {
					const pixel = pixels.data[i + 3]
					if (pixel === 0) {
						transPixels.push(pixel)
					}
				})

				if (transPixels.length / pixels.data.length > this.ratio) {
					this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
					this.canvas.removeEventListener(this.events[0], this.startMoveHandler)
					this.canvas.removeEventListener(this.events[1], this.moveHandler, false)
					document.removeEventListener(this.events[2], this.endMoveHandler, false)

					this.clearCallback()
				}
			},

			StartTouch() {
				this.start = false
			}
		}
	}
</script>
<style lang='scss'>
	.scratchCard {
		position: relative;
		width: 90%;
		height: 40vw;
		margin: 0 auto;

		.result {
			position: absolute;
			width: 100%;
			height: 100%;
			top: 0;
			left: 0;
		}

		.pic {
			width: 100%;
			height: 100%;
		}

		canvas {
			position: relative;
			z-index: 2;
			position: absolute;
		}

		.cavastext {
			z-index: 2;
			width: 100%;
			height: 100%;
			position: absolute;
			text-align: center;
			display: flex;
			align-items: center;
			justify-content: center;
			color: #FEEEC2;
		}
	}
</style>